﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;

namespace TuanHAShadowPriest
{
    public partial class Classname : CombatRoutine
    {
        #region Delegates

        public delegate WoWPoint LocationRetriverDelegate(object context);

        #endregion

        #region Basic Functions

        public override bool WantButton
        {
            get { return true; }
        }

        public override WoWClass Class
        {
            get { return WoWClass.Priest; }
        }

        public override string Name
        {
            get { return "TuanHA Shadow Priest for a Friend Request"; }
        }

        //public override Composite RestBehavior
        //{
        //    get { return RestRotation(); }
        //}

        public override Composite PreCombatBuffBehavior
        {
            get { return MainRotation(); }
        }

        //public override Composite PullBuffBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite PullBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite CombatBuffBehavior
        //{
        //    get { return MainRotation(); }
        //}

        public override Composite CombatBehavior
        {
            get { return MainRotation(); }
        }

        //public override Composite HealBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite MoveToTargetBehavior
        //{
        //    get { return CreateMoveToLosBehavior(); }
        //}

        public static LocalPlayer Me
        {
            get { return StyxWoW.Me; }
        }

        public override void Initialize()
        {
            Logging.Write("----------------------------------");
            Logging.Write("Hello " + Me.Race + " " + Me.Class);
            Logging.Write("Thank you for using TuanHA Shadow Priest");
            Logging.Write("----------------------------------");
            Logging.Write("Please be advised that this Combat Routine ONLY work with LazyRaider");
            Logging.Write("----------------------------------");
            Logging.Write("Use Control + H to toggle Halo ON/OFF");
            Logging.Write("----------------------------------");
            Logging.Write("Use Control + A to toggle AoE ON/OFF");
            Logging.Write("----------------------------------");

            //Disable for speed
            //Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", UpdateStatusEvent);
            //Lua.Events.AttachEvent("PLAYER_TALENT_UPDATE", UpdateMyTalentEvent);
            //Lua.Events.AttachEvent("GLYPH_ADDED", UpdateMyGlyphEvent);
            //Lua.Events.AttachEvent("WORLD_MAP_NAME_UPDATE", UpdateCurrentMapEvent);

            //BotEvents.Player.OnMapChanged += UpdateCurrentMapEvent;
            //BotEvents.OnBotStarted += OnBotStartedEvent;

            //Set Camera angle so you never have problem with it
            //console cameraSmoothTrackingStyle 0 (credit by alxaw - member of CLU dev team) 
            //Lua.DoString("RunMacroText(\"/console cameraSmoothTrackingStyle 0\")");

            //THSettings.Instance.UpdateStatus = true;

            UpdateMyGlyph();
        }

        //public override void OnButtonPress()
        //{
        //    var gui = new THForm();
        //    gui.ShowDialog();
        //}

        #endregion

        #region Function After this Region Order Alphabetically

        #endregion

        #region GetUnits

        internal static IEnumerable<WoWPartyMember> GroupMembers
        {
            get { return !Me.GroupInfo.IsInRaid ? Me.GroupInfo.PartyMembers : Me.GroupInfo.RaidMembers; }
        }

        //public List<WoWUnit> AllUnit = new List<WoWUnit>();
        //public List<WoWUnit> FarFriendlyPlayers = new List<WoWUnit>();
        //public List<WoWUnit> FarFriendlyUnits = new List<WoWUnit>();
        //public List<WoWPlayer> NearbyFriendlyPlayers = new List<WoWPlayer>();
        //public List<WoWUnit> NearbyFriendlyUnits = new List<WoWUnit>();
        public List<WoWPlayer> NearbyUnFriendlyPlayers = new List<WoWPlayer>();
        public List<WoWUnit> NearbyUnFriendlyUnits = new List<WoWUnit>();

        public void GetUnits()
        {
            //AllUnit.Clear();
            //NearbyFriendlyPlayers.Clear();
            NearbyUnFriendlyPlayers.Clear();
            //NearbyFriendlyUnits.Clear();
            NearbyUnFriendlyUnits.Clear();

            //AllUnit.Add(Me);
            //NearbyFriendlyUnits.Add(Me);
            //NearbyFriendlyPlayers.Add(Me);

            IEnumerable<WoWUnit> units =
                ObjectManager.GetObjectsOfType<WoWUnit>(true, true).Where(
                    p =>
                    (ValidUnit(p) || p.SummonedByUnitGuid == Me.Guid) &&
                    !Blacklist.Contains(p.Guid) &&
                    p.DistanceSqr <= 40*40);

            foreach (WoWUnit unit in units)
            {
                if (IsEnemy(unit))
                {
                    NearbyUnFriendlyUnits.Add(unit);

                    var player = unit as WoWPlayer;
                    if (player != null)
                    {
                        NearbyUnFriendlyPlayers.Add(player);
                    }
                }
            }
        }

        #endregion

        #region GetUnitAttack

        public WoWUnit UnitAttack;
        public WoWUnit UnitAttackASAP;
        public WoWUnit UnitAttackPet;

        private void GetUnitAttack()
        {
            UnitAttack = null;
            UnitAttackPet = null;
            UnitAttackASAP = null;

            if (UnitAttackASAP == null && Me.Combat)
            {
                using (StyxWoW.Memory.AcquireFrame())
                {
                    UnitAttack = (from unit in NearbyUnFriendlyUnits
                                  //Only search Target if in instance
                                  //where Me.IsInInstance
                                  orderby unit.DistanceSqr ascending
                                  //attack any unit if not in dungeon/raid
                                  where unit.Combat
                                  //where unit.GotTarget
                                  //only attack unit not tagged
                                  where
                                      unit.IsTargetingMeOrPet || unit.IsTargetingMyPartyMember ||
                                      unit.IsTargetingMyRaidMember
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();

                    //if it pet, try to find a player
                    if (UnitAttack != null && !UnitAttack.IsPlayer && !Me.CurrentMap.IsRaid && !Me.CurrentMap.IsDungeon)
                    {
                        UnitAttackPet = UnitAttack;
                        UnitAttack = (from unit in NearbyUnFriendlyPlayers
                                      orderby unit.DistanceSqr ascending
                                      where unit.Combat && unit.IsTargetingMeOrPet || Me.CurrentMap.IsBattleground
                                      where AttackableValid(unit)
                                      select unit).FirstOrDefault();

                        //can't find a player, kill the pet
                        if (UnitAttack == null && UnitAttackPet != null)
                        {
                            UnitAttack = UnitAttackPet;
                        }
                    }
                }
            }
        }

        #endregion

        #region Hold

        public static string MyCastingSpells = "[Fists of Fury]";

        public Composite Hold()
        {
            return
                new Decorator(
                    ret =>
                    Me.HasAura("Drink") || Me.HasAura("Food") ||
                    Me.IsCasting &&
                    (Me.ChanneledCastingSpellId != 0 ||
                     !MyCastingSpells.Contains(Me.CastingSpell.Name)) ||
                    !Me.IsAlive,
                    new Action(delegate { return RunStatus.Success; })
                    );
        }

        #endregion

        #region Pulse

        public bool UseHalo = true;
        public DateTime LastSwitch;
        public bool UseAoE = true;

        public override void Pulse()
        {
            //ObjectManager.Update();
            GetUnits();
            GetUnitAttack();

            if (GetAsyncKeyState(Keys.LControlKey) < 0 && GetAsyncKeyState(Keys.H) < 0 &&
                LastSwitch.AddSeconds(1) < DateTime.Now)
            {
                if (UseHalo)
                {
                    UseHalo = false;
                    LastSwitch = DateTime.Now;
                    //Lua.DoString("RunMacroText(\"/s Halo is OFF\")");
                    Lua.DoString("RunMacroText(\"/script msg='Halo OFF' print(msg)\")");
                }
                else
                {
                    UseHalo = true;
                    LastSwitch = DateTime.Now;
                    Lua.DoString("RunMacroText(\"/script msg='Halo ON' print(msg)\")");
                }
            }

            if (GetAsyncKeyState(Keys.LControlKey) < 0 && GetAsyncKeyState(Keys.A) < 0 &&
                LastSwitch.AddSeconds(1) < DateTime.Now)
            {
                if (UseAoE)
                {
                    UseAoE = false;
                    LastSwitch = DateTime.Now;
                    //Lua.DoString("RunMacroText(\"/s Halo is OFF\")");
                    Lua.DoString("RunMacroText(\"/script msg='AoE OFF' print(msg)\")");
                }
                else
                {
                    UseAoE = true;
                    LastSwitch = DateTime.Now;
                    Lua.DoString("RunMacroText(\"/script msg='AoE ON' print(msg)\")");
                }
            }
        }

        #endregion

        #region  BattleStandard

        public Composite UseBattleStandard()
        {
            return
                new Decorator(
                    ret =>
                    Me.Combat && Me.HealthPercent < 40 && Me.CurrentTarget != null &&
                    Me.CurrentTarget.CurrentHealth > Me.HealthPercent && Me.CurrentMap.IsBattleground,
                    new Action(delegate
                                   {
                                       if (Me.IsAlliance)
                                       {
                                           WoWItem bs = Me.BagItems.FirstOrDefault(o => o.Entry == 18606);
                                           //18606 Alliance Battle Standard

                                           if (!Me.HasAura("Alliance Battle Standard") && bs != null &&
                                               bs.CooldownTimeLeft.TotalMilliseconds <= MyLatency)
                                           {
                                               bs.Use();
                                               //Lua.DoString("RunMacroText(\"/5 Used Healthstone\")");
                                               //Lua.DoString("RunMacroText(\"/s Used Battle Standard\")");
                                               Logging.Write("Use Battle Standard at " + Me.HealthPercent + "%");
                                           }
                                       }

                                       if (Me.IsHorde)
                                       {
                                           WoWItem bs = Me.BagItems.FirstOrDefault(o => o.Entry == 18607);
                                           //18606 Horde Battle Standard

                                           if (!Me.HasAura("Horde Battle Standard") && bs != null &&
                                               bs.CooldownTimeLeft.TotalMilliseconds <= MyLatency)
                                           {
                                               bs.Use();
                                               //Lua.DoString("RunMacroText(\"/5 Used Healthstone\")");
                                               //Lua.DoString("RunMacroText(\"/s Used Battle Standard\")");
                                               Logging.Write("Use Battle Standard at " + Me.HealthPercent + "%");
                                           }
                                       }

                                       return RunStatus.Failure;
                                   })
                    );
        }

        #endregion

        #region UseHealthstone

        public Composite UseHealthstone()
        {
            return
                new Decorator(
                    ret =>
                    Me.Combat && Me.HealthPercent < 40 && Me.CurrentTarget != null &&
                    Me.CurrentTarget.CurrentHealth > Me.HealthPercent,
                    new Action(delegate
                                   {
                                       WoWItem hs = Me.BagItems.FirstOrDefault(o => o.Entry == 5512); //5512 Healthstone
                                       if (hs != null && hs.CooldownTimeLeft.TotalMilliseconds <= MyLatency)
                                       {
                                           hs.Use();
                                           //Lua.DoString("RunMacroText(\"/s Used Healthstone\")");
                                           Logging.Write("Use Healthstone at " + Me.HealthPercent + "%");
                                       }
                                       return RunStatus.Failure;
                                   })
                    );
        }

        #endregion

        #region MainRotation

        public static bool HelloFriend = false;
        public static bool IsConstantFace;
        public static bool IsOverrideModeOn = false;
        public static WoWUnit MyLastTarget;
        public static DateTime Now = DateTime.Now;
        public static Stopwatch PendingSpellStopWatch = new Stopwatch();
        public static DateTime TickMilisecond;
        public static DateTime TickMilisecondTotal;
        public static WoWUnit UnitHealFull;
        public static DateTime LastVT;

        public static bool CurrentTargetIsValid;
        public static bool CurrentTargetIsEnemy;
        public static bool CurrentTargetIsFacing;

        private static readonly HashSet<uint> SafeTarget = new HashSet<uint>
                                                               {
                                                                   60410, //Elegon
                                                                   60776, //Empyreal Focus
                                                                   60793, //Celestial Protector
                                                                   60913, //Energy Charge
                                                               };

        public Composite MainRotation()
        {
            return new PrioritySelector(
                new Decorator(ret => (!StyxWoW.IsInGame || !StyxWoW.IsInWorld || !Me.IsValid),
                              new Action(delegate
                                             {
                                                 Logging.Write(LogLevel.Diagnostic, "Error, Skip Main Rotation.");
                                                 return RunStatus.Success;
                                             })),
                new Action(delegate
                               {
                                   //Hold rotation on Hymn of Hope
                                   if (Me.IsChanneling && Me.ChanneledCastingSpellId == 64901)
                                   {
                                       Logging.Write(LogLevel.Diagnostic,
                                                     DateTime.Now.ToString("ss:fff ") +
                                                     "Hold All Action On Hymn of Hope");
                                       return RunStatus.Success;
                                   }

                                   //Clear Target if dead and still in combat
                                   if (Me.CurrentTarget != null && !Me.CurrentTarget.IsAlive && Me.Combat)
                                   {
                                       Lua.DoString("RunMacroText(\"/cleartarget\")");
                                   }

                                   //Clear Target if walk away from friendly
                                   if (Me.CurrentTarget != null && !Me.CurrentTarget.IsPlayer &&
                                       Me.CurrentTarget.IsFriendly &&
                                       Me.CurrentTarget.IsSafelyBehind(Me))
                                   {
                                       Lua.DoString("RunMacroText(\"/cleartarget\")");
                                   }


                                   //Hold dps on Dungeon or Raid
                                   if ((Me.CurrentMap.IsDungeon || Me.CurrentMap.IsRaid) &&
                                       Me.CurrentTarget != null &&
                                       !Me.CurrentTarget.Combat)
                                   {
                                       return RunStatus.Success;
                                   }

                                   //"Mind Spike" - 73510
                                   if (Me.IsCasting && Me.CastingSpellId == 73510 &&
                                       !Me.HasAura("Surge of Darkness"))
                                   {
                                       SpellManager.StopCasting();
                                   }

                                   //Fix bug casting Smite
                                   if (Me.IsCasting && Me.CastingSpellId == 585)
                                   {
                                       SpellManager.StopCasting();
                                       CastSpell("Shadowform", Me);
                                   }

                                   CurrentTargetIsValid = ValidUnit(Me.CurrentTarget) ||
                                                          Me.CurrentTarget != null &&
                                                          SafeTarget.Contains(Me.CurrentTarget.Entry);
                                   CurrentTargetIsEnemy = IsEnemy(Me.CurrentTarget);
                                   CurrentTargetIsFacing = CurrentTargetIsValid && (Me.IsFacing(Me.CurrentTarget) ||
                                                                                    Me.CurrentTarget != null &&
                                                                                    SafeTarget.Contains(Me.CurrentTarget.Entry));

                                   return RunStatus.Failure;
                               }
                    ),
                //Vampric embrace
                UseHealthstone(),
                UseBattleStandard(),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    (Me.CurrentMap.IsDungeon || Me.CurrentMap.IsRaid) &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    Me.CurrentTarget.ThreatInfo.RawPercent > 90 &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 10*10 &&
                    SpellManager.HasSpell("Fade"),
                    new Action(delegate
                                   {
                                       CastSpell("Fade", Me);
                                       return RunStatus.Failure;
                                   })
                    ),
                //new Decorator(
                //    ret =>
                //    !Me.Mounted &&
                //    Me.Combat &&
                //    !CastingorGCDL() &&
                //    !Me.HasAura("Vampric Embrace") &&
                //    SpellManager.HasSpell("Vampiric Embrace") &&
                //    SpellManager.Spells["Vampiric Embrace"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                //    new Action(delegate
                //                   {
                //                       CastSpell("Vampiric Embrace", Me);
                //                       return RunStatus.Failure;
                //                   })
                //    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    LastVT.AddSeconds(3) < DateTime.Now &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !Me.IsMoving &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.4 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !GCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Vampiric Touch") &&
                    MyAuraTimeLeft("Vampiric Touch", Me.CurrentTarget) < 6000,
                    new Action(delegate
                                   {
                                       SpellManager.StopCasting();
                                       CastSpell("Vampiric Touch", Me.CurrentTarget);
                                       LastVT = DateTime.Now;
                                   })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !Me.IsMoving &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.1 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    Me.CurrentTarget.HealthPercent <= 20 &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Shadow Word: Death") &&
                    SpellManager.Spells["Shadow Word: Death"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Shadow Word: Death", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.8 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    Me.GetCurrentPower(WoWPowerType.ShadowOrbs) > 2 &&
                    MyAuraTimeLeft("Devouring Plague", Me.CurrentTarget) < 3000 &&
                    SpellManager.HasSpell("Devouring Plague"),
                    new Action(delegate { CastSpell("Devouring Plague", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    MyAuraTimeLeft("Shadow Word: Pain", Me.CurrentTarget) < 3000 &&
                    SpellManager.HasSpell("Shadow Word: Pain"),
                    new Action(delegate { CastSpell("Shadow Word: Pain", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    UseAoE &&
                    !Me.Mounted &&
                    Me.ManaPercent > 50 &&
                    !CastingorGCDL() &&
                    SpellManager.HasSpell("Shadow Word: Pain") &&
                    GetUnitSWP(),
                    new Action(delegate { CastSpell("Shadow Word: Pain", UnitSWP); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    Me.GetAuraById(124430) != null &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.4 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.Spells["Mind Blast"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Mind Blast", Me.CurrentTarget); })
                    ),
                //Mind Spike with Glyph
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    Me.HasAura("Surge of Darkness") &&
                    HasGlyph.Contains("Glyph of Mind Spike"),
                    new Action(delegate { CastSpell("Mind Spike", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    UseAoE &&
                    !Me.Mounted &&
                    !CastingorGCDL() &&
                    SpellManager.HasSpell("Mind Sear") &&
                    GetUnitMindSear(),
                    new Action(delegate { CastSpell("Mind Sear", UnitMindSear); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !Me.IsMoving &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.4 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Mind Blast") &&
                    SpellManager.Spells["Mind Blast"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Mind Blast", Me.CurrentTarget); })
                    ),
                //Mind Spike without Glyph
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    Me.HasAura("Surge of Darkness"),
                    new Action(delegate { CastSpell("Mind Spike", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    UseHalo &&
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !Me.IsMoving &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.4 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr > 22*22 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    !IsHaloSafe() &&
                    SpellManager.HasSpell("Halo") &&
                    SpellManager.Spells["Halo"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Halo", Me); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    Me.IsFacing(Me.CurrentTarget) &&
                    Me.GotAlivePet &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Mindbender") &&
                    SpellManager.Spells["Mindbender"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Mindbender", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    Me.IsFacing(Me.CurrentTarget) &&
                    (Me.CurrentTarget.CurrentHealth > Me.CurrentHealth*0.8 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    !CastingorGCDL() &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Shadowfiend") &&
                    SpellManager.Spells["Shadowfiend"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Shadowfiend", Me.CurrentTarget); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    Me.Combat &&
                    !CastingorGCDL() &&
                    (Me.ManaPercent < 10 || Me.HealthPercent < 20) &&
                    SpellManager.HasSpell("Dispersion") &&
                    SpellManager.Spells["Dispersion"].CooldownTimeLeft.TotalMilliseconds <= MyLatency,
                    new Action(delegate { CastSpell("Dispersion", Me); })
                    ),
                //Mind Flay
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    !Me.IsCasting &&
                    CurrentTargetIsValid &&
                    CurrentTargetIsEnemy &&
                    CurrentTargetIsFacing &&
                    !Me.IsMoving &&
                    (Me.CurrentTarget.CurrentHealth > Me.MaxHealth*0.4 ||
                     Me.CurrentTarget.Name.Contains("Dummy")) &&
                    (!CastingorGCDL() ||
                     Me.IsCasting && Me.ChanneledCastingSpellId == 15407 &&
                     Me.CurrentCastTimeLeft.TotalMilliseconds < 1000) &&
                    Me.CurrentTarget.DistanceSqr < 40*40 &&
                    Me.CurrentTarget.InLineOfSpellSight &&
                    SpellManager.HasSpell("Mind Flay"),
                    new Action(delegate { CastSpell("Mind Flay", Me.CurrentTarget); })
                    ),
                //Shadowform
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    !CastingorGCDL() &&
                    !Me.HasAura("Shadowform") &&
                    SpellManager.HasSpell("Shadowform"),
                    new Action(delegate { CastSpell("Shadowform", Me); })
                    ),
                //Power Word: Shield
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    !CastingorGCDL() &&
                    Me.Combat && Me.IsMoving &&
                    !Me.HasAura("Weakened Soul") &&
                    SpellManager.HasSpell("Body and Soul") &&
                    SpellManager.HasSpell("Power Word: Shield"),
                    new Action(delegate { CastSpell("Power Word: Shield", Me); })
                    ),
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    !CastingorGCDL() &&
                    !Me.HasAura("Inner Fire") &&
                    SpellManager.HasSpell("Inner Fire"),
                    new Action(delegate { CastSpell("Inner Fire", Me); })
                    ),
                // Power Word: Fortitude
                new Decorator(
                    ret =>
                    !Me.Mounted &&
                    !CastingorGCDL() &&
                    !Me.HasAura("Power Word: Fortitude") &&
                    !Me.HasAura("Commanding Shout") &&
                    SpellManager.HasSpell("Power Word: Fortitude"),
                    new Action(delegate { CastSpell("Power Word: Fortitude", Me); })
                    )
                )
                ;
        }

        #endregion
    }
}